/**
 * rndf.h
 *
 * This set of structs defines a convenient format for storing
 * and accessing the Route Network Definition and the Mission Definition.
 */ 

#ifndef ROUTE_DEFINITION_H
#define ROUTE_DEFINITION_H

#ifdef __cplusplus
extern "C" {
#endif
	
typedef enum {
    RNDF_BOUND_UNSPECIFIED=0,
    RNDF_BOUND_DBL_YELLOW=1,
    RNDF_BOUND_SOLID_WHITE=2,
    RNDF_BOUND_BROKEN_WHITE=3,
    RNDF_BOUND_SOLID_YELLOW=4,
} RndfBoundaryType;
  
typedef enum {
    RNDF_POINT_WAYPOINT=0,
    RNDF_POINT_PERIMETER=1,
    RNDF_POINT_SPOT=2,
} RndfPointType;

typedef struct _RndfSpeedlimit RndfSpeedlimit;
typedef struct _RndfMission RndfMission;
typedef struct _RndfRouteNetwork RndfRouteNetwork;
typedef struct _RndfSegment RndfSegment;
typedef struct _RndfLane RndfLane;
typedef struct _RndfWaypoint RndfWaypoint;
typedef struct _RndfZone RndfZone;
typedef struct _RndfSpot RndfSpot;
typedef struct _RndfCheckpoint RndfCheckpoint;
typedef struct _RndfObstacle RndfObstacle;

struct _RndfObstacle {
    int id;          // id
    double lat, lon; // latitude and longitude of the center
    double w1, w2;   // width and height (in meters)
    double height;   // height (in meters)
    double orient;   // orientation of the obstacle wrt north (in degrees)
};

struct _RndfSpeedlimit {
    int max_speed;
    int min_speed;
    int id;         // id of the segment
};

struct _RndfMission {
    char * name;
    RndfRouteNetwork * route;
    char *route_name;
    char * format_version;
    char * creation_date;
    int num_checkpoints;
    RndfCheckpoint ** checkpoints;
    int *checkpoint_ids;
    int num_speed_limits;
    RndfSpeedlimit * speed_limits;
    int valid;
};
	
struct _RndfRouteNetwork {

    char * name;
    int num_segments;
    RndfSegment * segments;
    int num_zones;
    RndfZone * zones;
    int num_checkpoints;
    RndfCheckpoint * checkpoints;
    char * format_version;
    char * creation_date;
    int valid;
    int max_checkpoint_id;

    RndfObstacle * obstacles;
    int num_obstacles;
};

struct _RndfSegment {
    RndfRouteNetwork * parent;
    int id;
    int num_lanes;
    RndfLane * lanes;
    char * name;
    int max_speed, min_speed;
};

struct _RndfLane {
    RndfSegment * parent;
    int id;
    int num_waypoints;
    RndfWaypoint * waypoints;
    int lane_width;
    RndfBoundaryType left_boundary;
    RndfBoundaryType right_boundary;
};

/* There are several waypoint variants: waypoints of lanes, zone perimeter
 * points, and parking spot points.  Thus, this common "Waypoint" struct is
 * used for all three types.  The "type" field indicates which of the three,
 * and the type of the "parent" field can be specified accordingly with the
 * union. */
struct _RndfWaypoint {
    RndfPointType type;
    union {
        RndfLane * lane;
        RndfZone * zone;
        RndfSpot * spot;
    } parent;
    int id;
    double lat, lon;
    int is_stop;
    int num_exits;
    RndfWaypoint ** exits;
    void * user_data;
    char dense; /* true if this waypoint was generated by densification */
};

struct _RndfZone {
    RndfRouteNetwork * parent;
    int id;
    int num_spots;
    RndfSpot * spots;
    int num_peripoints;
    RndfWaypoint * peripoints;
    char * name;
    int max_speed, min_speed;
};

struct _RndfSpot {
    RndfZone * parent;
    int id;
    int spot_width;
    RndfWaypoint waypoints[2];
    int checkpoint_id;
};

struct _RndfCheckpoint {
    int id;
    RndfWaypoint * waypoint;
};

#ifdef __cplusplus
};
#endif

#endif
